//
//  RegionViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/25/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit


protocol RegionViewControllerDelegate: class {
    func selectCity (city: [City])
}

final class RegionViewController: UIViewController, Alertable {

    // MARK: - Outlets
    
    private lazy var tableView: UITableView = {
        let table = UITableView()
        table.register(OptionCell.self, forCellReuseIdentifier: "optionCell")
        table.separatorStyle = .none
        table.tableFooterView = UIView()
        table.backgroundColor = .clear
        table.delegate = self
        table.dataSource = self
        table.showsVerticalScrollIndicator = false
        return table
    }()
    
    private lazy var searchBar: UISearchBar = {
        let searchBar = UISearchBar()
        searchBar.placeholder = "Город, населенный пункт"
        
        searchBar.textField.clipsToBounds = true
        searchBar.textField.layer.cornerRadius = 15
        searchBar.delegate = self
        searchBar.backgroundImage = UIImage()
        return searchBar
    }()
    
    private lazy var submitBtn: UIButton = {
        let btn = UIButton ()
        btn.backgroundColor = .blueColor
        btn.setTitleColor(.white, for: .normal)
        btn.setTitle("Готово", for: .normal)
        btn.titleLabel!.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        btn.clipsToBounds = true
        btn.layer.cornerRadius = 15
        return btn
    }()
    
    private lazy var spinnerView = SpinnerView()
    
    // MARK: - Properties
    
    private lazy var model = RegionModel()
    private var optionsViewModel = OptionsViewModel()
    private var filteredModel:[String: [OptionViewModel]] = [:]
    weak var delegate: RegionViewControllerDelegate!
    
    struct LastSelection {
        var row: Int
        var optionIndex: Int?
    }
    
    private var lastSelection: LastSelection?
    
    private var isLoading: Bool = false {
        didSet {
            isLoading ? spinnerView.startAnimating() : spinnerView.stopAnimating()
            self.view.isUserInteractionEnabled = !isLoading
        }
    }
    
    private var isCarCreate: Bool {
        return delegate is ContactsViewController
    }
    
    // MARK: - Actions
    
    @objc private func goBack (sender: Any) {
        self.returnBack()
    }
    
    @objc private func onReset (sender: Any) {
        optionsViewModel.reset()
        lastSelection = nil
        tableView.reloadSections(IndexSet(arrayLiteral: 0), with: .left)
    }
    
    @objc private func onReady (sender: Any) {
        let selectedCity = model.toCityFormat(options: optionsViewModel.options)
        delegate.selectCity(city: selectedCity)
        self.returnBack()
    }
    
    @objc private func closeVC (sender: UIBarButtonItem) {
        self.navigationController?.dismiss(animated: true, completion: nil)
    }
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        optionsViewModel.setUpOptions(options: model.options)
        self.addView()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        isLoading = true
        NotificationCenter.default.addObserver(self, selector: #selector(updateOptions(notification:)), name: NSNotification.Name(rawValue: "regionUpdate"), object: nil)
        model.loadData()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        self.setUpNavBar()
    }
}


// MARK: - Methods

extension RegionViewController {
    
    @objc func updateOptions (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            let error = userInfo["error"] as? Bool
            
            if (error ?? false) {
                let data = userInfo["data"] as! RequestError
                switch data {
                case .general:
                    self.showAlert("Упс...", "Неизвестная ошибка")
                case .parameter(let msg):
                    self.showAlert("Упс...", msg)
                }
            } else {
                let data = userInfo["data"] as! [[String: Any]]
                optionsViewModel.setUpOptions(options: data) {
                    self.filteredModel = self.optionsViewModel.options
                    self.tableView.reloadData()
                    NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "regionUpdate"), object: nil)
                }
            }
        }
        isLoading = false
    }
    
    private func returnBack () {
        self.navigationController?.popViewController(animated: true)
    }
}


extension RegionViewController: OptionCellDelegate, UISearchBarDelegate {
    
    func didSelectCell(at indexPath: IndexPath, optionIndex: Int?) {
        let title = "Все регионы"
    
        /// - Select New Row
        
        if let _optionIndex = optionIndex {
            filteredModel[title]![indexPath.row].option.items![_optionIndex].isSelected?.toggle()
            
            /// - Deselect, if only single-row selection mode
            
            if isCarCreate && lastSelection != nil {
                 if let _optionIndex = lastSelection!.optionIndex {
                     filteredModel[title]![lastSelection!.row].option.items![_optionIndex].isSelected = false
                 }
                 tableView.reloadRows(at: [IndexPath(row: lastSelection!.row, section: 0)], with: .middle)
             }
            
            lastSelection = LastSelection(row: indexPath.row, optionIndex: _optionIndex)
        } else {
            if (optionsViewModel.options[title]![indexPath.row].option.isSingle ?? false) {
                filteredModel[title]![indexPath.row].option.isSelected?.toggle()
            } else {
                filteredModel[title]![indexPath.row].isExpanded?.toggle()
            }
        }
        
        tableView.reloadRows(at: [indexPath], with: .middle)
    }
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        let items = optionsViewModel.options["Все регионы"]!.filter {
            searchText.isEmpty || $0.title.lowercased().contains(searchText.lowercased())
        }
        self.filteredModel["Все регионы"] = items
        tableView.reloadData()
    }
}


// MARK: - Table View Configuration

extension RegionViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if filteredModel.count == 0 {
            return 0
        } else {
            let index = filteredModel.index(filteredModel.startIndex, offsetBy: section)
            return filteredModel[index].value.count
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "optionCell") as! OptionCell
        cell.indexPath = indexPath
        cell.delegate = self
        cell.addTap(isCarCreate: isCarCreate)
        cell.optionModel = filteredModel["Все регионы"]![indexPath.row]
        cell.selectionStyle = .none
        cell.backgroundColor = .clear
        cell.contentView.backgroundColor = .clear
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if !isCarCreate {
            let _view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 40))
            _view.backgroundColor = .whiteBlueColor
            
            let title = "Все регионы"
            
            let lbl = UILabel()
            lbl.font = UIFont.systemFont(ofSize: 18, weight: .bold)
            lbl.text = title
            _view.addSubview(lbl)
            
            lbl.snp.makeConstraints { (make) in
                make.centerY.equalToSuperview()
                make.leading.trailing.equalToSuperview().inset(16)
            }
            return _view
        } else { return nil }
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return isCarCreate ? 0 : 40.0
    }
}


// MARK: - UI

extension RegionViewController {
    private func addView() {
        if isCarCreate {
            self.view.backgroundColor = .white
        } else {
            self.setGradientBackground()
        }
        self.view.addSubview(tableView)
        self.view.addSubview(submitBtn)
        self.view.addSubview(spinnerView)
        
        if !isCarCreate {
            self.view.addSubview(searchBar)
        }
        
        submitBtn.addTarget(self, action: #selector(onReady(sender:)), for: .touchUpInside)
        self.addConstraints()
    }
    
    private func addConstraints () {
        
        if !isCarCreate {
            searchBar.snp.makeConstraints { (make) in
                make.top.equalTo(view.safeAreaLayoutGuide).offset(16)
                make.leading.trailing.equalToSuperview().inset(8)
                make.height.equalTo(32)
            }
            tableView.snp.makeConstraints { (make) in
                make.top.equalTo(searchBar.snp.bottom).offset(24)
            }
        } else {
            tableView.snp.makeConstraints { (make) in
                make.top.equalTo(view.safeAreaLayoutGuide).offset(16)
            }
        }
    
        submitBtn.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(44)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-20)
        }
        tableView.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(submitBtn.snp.top).offset(-20)
        }
        spinnerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
    }
    
    private func setGradientBackground () {
        let colorTop = UIColor.rgb(253, 254, 255).cgColor
        let colorBottom = UIColor.whiteBlueColor.cgColor
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [colorTop, colorBottom]
        gradientLayer.locations = [0.0, 0.15]
        gradientLayer.frame = self.view.bounds
        self.view.layer.insertSublayer(gradientLayer, at:0)
    }
    
    private func setUpNavBar() {
        self.navigationController?.navigationBar.backgroundColor = .white
        self.navigationController?.navigationBar.isHidden = false
        self.navigationController?.navigationBar.defaultNavBar()
        self.navigationItem.hidesBackButton = true
        
        
        if isCarCreate {
            self.navigationItem.title = "Город"
            self.navigationItem.largeTitleDisplayMode = .always
            self.addCloseIcon()
        } else {
            self.navigationItem.largeTitleDisplayMode = .never
            self.navigationItem.title = "Регион"
            let resetBtn = UIBarButtonItem(title: "Сбросить", style: .plain, target: self, action: #selector(onReset(sender:)))
            self.navigationItem.rightBarButtonItem = resetBtn
        }
        
        let backIcon = UIImage(named: "cancel")
        let backButton = UIBarButtonItem(image: backIcon, landscapeImagePhone: backIcon, style: .plain, target: self, action: #selector(goBack(sender:)))
        backButton.tintColor = .greyColor
        
        self.navigationItem.leftBarButtonItem = backButton
    }

    private func addCloseIcon () {
        let closeBarBnt = UIBarButtonItem(image: UIImage(named: "dismiss"), style: .plain, target: self, action: #selector(closeVC))
        closeBarBnt.tintColor = .greyColor
        self.navigationItem.rightBarButtonItem = closeBarBnt
    }
}
